package yunjiao.javatutorials.guava.concurrent;

import com.google.common.util.concurrent.AbstractIdleService;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 连接池管理服务
 *
 * @author yangyunjiao
 */
public class DatabaseConnectionService extends AbstractIdleService {
    private final String url;
    private final String username;
    private final String password;
    private final int poolSize;
    private BlockingQueue<Connection> connectionPool;

    public DatabaseConnectionService(String url, String username, String password, int poolSize) {
        this.url = url;
        this.username = username;
        this.password = password;
        this.poolSize = poolSize;
    }

    @Override
    protected void startUp() throws Exception {
        System.out.println("Initializing database connection pool with size: " + poolSize);

        connectionPool = new LinkedBlockingQueue<>(poolSize);

        // 初始化连接池
        for (int i = 0; i < poolSize; i++) {
            Connection connection = DriverManager.getConnection(url, username, password);
            connectionPool.offer(connection);
        }

        System.out.println("Database connection pool initialized with " + connectionPool.size() + " connections");
    }

    @Override
    protected void shutDown() throws Exception {
        System.out.println("Shutting down database connection pool");

        if (connectionPool != null) {
            Connection connection;
            while ((connection = connectionPool.poll()) != null) {
                try {
                    if (!connection.isClosed()) {
                        connection.close();
                    }
                } catch (Exception e) {
                    System.err.println("Error closing connection: " + e.getMessage());
                }
            }
        }

        System.out.println("Database connection pool shutdown completed");
    }

    public Connection getConnection() throws InterruptedException {
        if (!isRunning()) {
            throw new IllegalStateException("Service is not running");
        }
        return connectionPool.take();
    }

    public void releaseConnection(Connection connection) {
        if (connection != null && isRunning()) {
            connectionPool.offer(connection);
        }
    }

    public int getAvailableConnections() {
        return connectionPool.size();
    }
}
